﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace ChatTool
{
    class VideoAPI
    {
        //  视频ＡＰＩ调用
        [DllImport("avicap32.dll")]//该函数用于创建一个视频捕捉窗口
        public static extern IntPtr capCreateCaptureWindowA(byte[] lpszWindowName, int dwStyle, int x, int y, int nWidth, int nHeight, IntPtr hWndParent, int nID);
        [DllImport("avicap32.dll")]//视频输入设备可以用capGetDriverDescriptionA来获得
        public static extern bool capGetDriverDescriptionA(short wDriver, byte[] lpszName, int cbName, byte[] lpszVer, int cbVer);
        [DllImport("User32.dll", SetLastError = true)]//用于向Windows系统发送消息机制
        public static extern bool SendMessage(IntPtr hWnd, int wMsg, short wParam, int lParam);
        [DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]//释放句柄所指代的窗体
        public static extern bool DestroyWindow(IntPtr hwnd);
        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags);
        //  常量
        public const int WM_USER = 0x400;
        public const int WS_CHILD = 0x40000000;//标识窗口风格//capCreateCaptureWindowA
        public const int WS_VISIBLE = 0x10000000;//标识窗口风格//capCreateCaptureWindowA
        public const int SWP_NOMOVE = 0x2;//
        public const int SWP_NOZORDER = 0x4;//
        public const int SWP_BOTTOM = 0x1;//
        public const int WM_CAP_DRIVER_CONNECT = WM_USER + 10;//连接视频采集驱动的消息
        public const int WM_CAP_DRIVER_DISCONNECT = WM_USER + 11;//和设备断开连接的消息
        public const int WM_CAP_EDIT_COPY = WM_USER + 30;//将捕获的视频信息放到剪贴板中的消息
        public const int WM_CAP_SET_CALLBACK_FRAME = WM_USER + 5;
        public const int WM_CAP_SET_PREVIEW = WM_USER + 50;//开始从摄像机获取预览图片的消息
        public const int WM_CAP_SET_PREVIEWRATE = WM_USER + 52;//设定预览时每milliseconds的帧率的消息
        public const int WM_CAP_SET_SCALE = WM_USER + 53;//设定预览界面的尺度缩放大小
        public const int WM_CAP_SET_VIDEOFORMAT = WM_USER + 45;
       

        public const int WM_CAP_START = WM_USER;
        public const int WM_CAP_SAVEDIB = WM_CAP_START + 25;//视频拍照的消息
        public const int WM_CAP_SEQUENCE = WM_CAP_START + 62;
        public const int WM_CAP_STOP = WM_CAP_START + 68;
        public const int WM_CAP_FILE_SET_CAPTURE_FILEA = WM_CAP_START + 20;
        public const int WM_CAP_GRAB_FRAME = WM_CAP_START + 60;
        public const int WM_CAP_SEQUENCE_NOFILE = WM_CAP_START + 63;
        public const int WM_CAP_SET_OVERLAY = WM_CAP_START + 51;
        public const int WM_CAP_SET_CALLBACK_VIDEOSTREAM = WM_CAP_START + 6;
        public const int WM_CAP_SET_CALLBACK_ERROR = WM_CAP_START + 2;
        public const int WM_CAP_SET_CALLBACK_STATUSA = WM_CAP_START + 3;
    }
    public class Cvideo     //视频类
    {
        private IntPtr lwndC;       //保存无符号句柄
        /// <summary>
        /// 打开视频设备
        /// </summary>
        public bool StartWebCam(IntPtr mControlPtr, int mWidth, int mHeight)
        {
            byte[] lpszName = new byte[100];
            byte[] lpszVer = new byte[100];
            //视频输入设备可以用capGetDriverDescriptionA来获得
            VideoAPI.capGetDriverDescriptionA(0, lpszName, 100, lpszVer, 100);
            //在pictureBox中打开预览界面
            this.lwndC = VideoAPI.capCreateCaptureWindowA(lpszName, VideoAPI.WS_CHILD | VideoAPI.WS_VISIBLE, 0, 0, mWidth, mHeight, mControlPtr, 0);
            VideoAPI.SendMessage(lwndC, VideoAPI.WM_CAP_SET_CALLBACK_VIDEOSTREAM, 0, 0);
            VideoAPI.SendMessage(lwndC, VideoAPI.WM_CAP_SET_CALLBACK_ERROR, 0, 0);
            VideoAPI.SendMessage(lwndC, VideoAPI.WM_CAP_SET_CALLBACK_STATUSA, 0, 0);

            if (VideoAPI.SendMessage(lwndC, VideoAPI.WM_CAP_DRIVER_CONNECT, 0, 0))//连接摄像设备
            {
                VideoAPI.SendMessage(lwndC, VideoAPI.WM_CAP_SET_SCALE, 1, 0);//设定预览界面的尺度缩放大小
                VideoAPI.SendMessage(lwndC, VideoAPI.WM_CAP_SET_PREVIEWRATE, 100, 0);//设定预览时每milliseconds的帧率
                VideoAPI.SendMessage(lwndC, VideoAPI.WM_CAP_SET_OVERLAY, 1, 0);
                VideoAPI.SendMessage(lwndC, VideoAPI.WM_CAP_SET_PREVIEW, 1, 0);//开始从摄像机获取预览图片
                VideoAPI.SetWindowPos(lwndC, VideoAPI.SWP_BOTTOM, 0, 0, mWidth, mHeight, (VideoAPI.SWP_NOMOVE | VideoAPI.SWP_NOZORDER));//调整预览窗体大小为pictureBox大小
                return true;
            }
            else
            {
                return false;
            }
        }
        /// <summary>
        /// 关闭视频设备
        /// </summary>
        public void CloseWebcam()
        {
            VideoAPI.SendMessage(lwndC, VideoAPI.WM_CAP_DRIVER_DISCONNECT, 0, 0);//和设备断开连接
            VideoAPI.DestroyWindow(this.lwndC);//关闭窗体
        }
        ///   <summary>   
        ///   拍摄照片
        ///   </summary>   
        ///   <param   name="path">要保存bmp文件的路径</param>   
        public void GrabImage(string path)
        {
            //将托管 System.String 中的内容复制到非托管内存，并在复制时转换为 ANSI 格式。
            //使用 2 个字节来代表一个字符的各种汉字延伸编码方式，称为 ANSI 编码
            IntPtr hBmp = Marshal.StringToHGlobalAnsi(path);
            VideoAPI.SendMessage(lwndC, VideoAPI.WM_CAP_SAVEDIB, 0, hBmp.ToInt32());//发送拍照消息
        }
        /// <summary>
        /// 将捕获的视频信息放到剪贴板中
        /// </summary>
        public void CaptureWindow()
        {
            VideoAPI.SendMessage(lwndC, VideoAPI.WM_CAP_EDIT_COPY, 0, 0);
        }
        ///   <summary>   
        ///   开始录像
        ///   </summary>   
        ///   <param   name="path">要保存录像的路径</param>   
        public void StarKinescope(string path)
        {
            IntPtr hBmp = Marshal.StringToHGlobalAnsi(path);
            VideoAPI.SendMessage(lwndC, VideoAPI.WM_CAP_FILE_SET_CAPTURE_FILEA, 0, hBmp.ToInt32());
            VideoAPI.SendMessage(lwndC, VideoAPI.WM_CAP_SEQUENCE, 0, 0);
        }
        /// <summary>
        /// 停止录像
        /// </summary>
        public void StopKinescope()
        {
            VideoAPI.SendMessage(lwndC, VideoAPI.WM_CAP_STOP, 0, 0);
        }

    }

}
